The Developer Fastlane

« 365 days to become a developer » challenge

PHP: Password hash

November 15, 2020

Lesson

Purpose

For security reasons, it is forbidden to store clear passwords directly in the page code or in a database.

Why we chose to hash the password

There are two solutions to secure passwords:
  1. Encryption: functions modifying the password (e.g. replacing characters with other characters according to a set of predefined rules).
  2. Hashing: Generating a signature for a string of characters. Signature = description of the characteristics of the password (example: length, type, etc. but in a more complex version). The result is a string of characters, a kind of code, which allows you to check if an entered password matches the signature. It is not possible to find the password in reverse.

Hash functions

There are 2 functions in PHP to hash passwords:
  1. password_hash(): to generate a signature based on a password (PHP Doc)
  2. password_verify(): to verify if the password matches a given signature (PHP Doc)
Both functions are detailed below.

1. password_hash()

  • $var1: password
  • $var2: algorithm to use. We use the constants listed on this page: PHP Doc. Very often the default value (PASSWORD_DEFAULT) is used.
  • $var3: salt (quite never used) and cost. The cost allows to increase the time to generate the signature (this will make it more time/difficult for a hacker to decrypt the password). By default, the cost is 10. The higher this number is, the longer it will take the processor to generate a signature. In 2020 we tend to put a cost of 13.
Code
echo password_hash('Doe', PASSWORD_DEFAULT, ['cost' => 13]);
Output: the password_hash() function returns a string which is the signature of the password:
Result
$2y$13$EA0EdRogXIqAPx9HTkcCo.u7Cbbp5xfgf1jLM8i3WlV3E59/9wAwe
  • In the above signature generated, the cost is $13 (4th position).
  • Now that we have generated the password signature, we want to check if the password entered by the user matches the signature.

2. password_verify()

  • $var1: password entered by the user.
  • var2: signature (previously generated with password_hash)
Code
// Instead of doing the verification this way (unsecured)...
    
if ($_POST['password'] === 'Doe') {
    /* do something */ 
}
    
// ...we use this (secure version with hash):
    
$signature = '$2y$13$EA0EdRogXIqAPx9HTkcCo.u7Cbbp5xfgf1jLM8i3WlV3E59/9wAwe';
if (password_verify($_POST['password'], $signature])) { 
    /* do something */
}
© 2020 - Edouard Proust | The Developer Fastlane